import pytest
import requests
import json
from unittest.mock import patch, MagicMock
import time
import random

# 配置信息
API_URL = "https://cvm.tencentcloudapi.com/"
REGION = "ap-guangzhou"
SECRET_ID = "your-secret-id"
SECRET_KEY = "your-secret-key"


def generate_signature(params, SECRET_KEY):
    """生成签名（模拟实现）"""
    return "mock-signature"


def send_request(action, params=None):
    """发送API请求（模拟实现）"""
    if params is None:
        params = {}
    common_params = {
        "Action": action,
        "Version": "2017-03-12",
        "Region": REGION,
        "SecretId": SECRET_ID,
        "Timestamp": int(time.time()),
        "Nonce": random.randint(1, 1000000),
        "SignatureMethod": "HmacSHA256"
    }
    all_params = {**common_params, **params}
    all_params["Signature"] = generate_signature(all_params, SECRET_KEY)

    response = requests.post(API_URL, data=all_params)
    return response.json()


class TestStartInstances:
    @patch('requests.post')
    def test_success(self, mock_post):
        """测试成功启动实例"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "RequestId": "1234567890",
                "OperationProgress": {
                    "TotalCount": 1,
                    "SuccessCount": 1,
                    "FailedCount": 0
                }
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-123456"]}
        result = send_request("StartInstances", params)

        assert "Response" in result
        assert "RequestId" in result["Response"]
        assert "OperationProgress" in result["Response"]

    @patch('requests.post')
    def test_internal_error(self, mock_post):
        """测试内部错误"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InternalServerError",
                    "Message": "操作内部错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("StartInstances", {"InstanceIds": ["ins-123456"]})
        assert result["Response"]["Error"]["Code"] == "InternalServerError"

    @patch('requests.post')
    def test_unsupported_instance(self, mock_post):
        """测试不支持的实例"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidInstance.NotSupported",
                    "Message": "不被支持的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-unsupported"]}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "InvalidInstance.NotSupported"

    @patch('requests.post')
    def test_invalid_instance_id_format(self, mock_post):
        """测试无效实例ID格式"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidInstanceId.Malformed",
                    "Message": "无效实例ID。指定的实例ID格式错误。例如实例ID长度错误ins-1122"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-123"]}  # 长度错误的实例ID
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "InvalidInstanceId.Malformed"

    @patch('requests.post')
    def test_instance_not_found(self, mock_post):
        """测试实例不存在"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidInstanceId.NotFound",
                    "Message": "没有找到相应实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-not-found"]}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "InvalidInstanceId.NotFound"

    @patch('requests.post')
    def test_invalid_parameter_value(self, mock_post):
        """测试参数取值错误"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameterValue",
                    "Message": "参数取值错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InvalidParam": "invalid"}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "InvalidParameterValue"

    @patch('requests.post')
    def test_invalid_instance_id_format_strict(self, mock_post):
        """测试实例ID格式不符合要求"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameterValue.InstanceIdMalformed",
                    "Message": "实例ID不合要求，请提供规范的实例ID，类似ins-xxxxxxxx，字母x代表小写字符或数字"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["INS-123456"]}  # 包含大写字母的实例ID
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "InvalidParameterValue.InstanceIdMalformed"

    @patch('requests.post')
    def test_parameter_limit_exceeded(self, mock_post):
        """测试参数值数量超过限制"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameterValue.LimitExceeded",
                    "Message": "参数值数量超过限制"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-" + str(i) for i in range(101)]}  # 假设限制为100个
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "InvalidParameterValue.LimitExceeded"

    @patch('requests.post')
    def test_unsupported_zone(self, mock_post):
        """测试不支持的可用区"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameterValue.ZoneNotSupported",
                    "Message": "请求不支持该可用区"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-123456"], "Zone": "invalid-zone"}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "InvalidParameterValue.ZoneNotSupported"

    @patch('requests.post')
    def test_missing_parameter(self, mock_post):
        """测试缺少必要参数"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "MissingParameter",
                    "Message": "缺少参数错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        result = send_request("StartInstances", {})
        assert result["Response"]["Error"]["Code"] == "MissingParameter"

    @patch('requests.post')
    def test_mutex_operation(self, mock_post):
        """测试相同任务正在运行"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "MutexOperation.TaskRunning",
                    "Message": "同样的任务正在运行"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-task-running"]}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "MutexOperation.TaskRunning"

    @patch('requests.post')
    def test_instance_operation_in_progress(self, mock_post):
        """测试实例正在执行其他操作"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "OperationDenied.InstanceOperationInProgress",
                    "Message": "实例正在执行其他操作，请稍后再试"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-in-progress"]}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "OperationDenied.InstanceOperationInProgress"

    @patch('requests.post')
    def test_instance_reinstall_failed(self, mock_post):
        """测试实例重装系统失败"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceReinstallFailed",
                    "Message": "当前实例为重装系统失败状态，不支持此操作；推荐您再次重装系统，也可以销毁/退还实例或提交工单"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-reinstall-failed"]}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceReinstallFailed"

    @patch('requests.post')
    def test_instance_state_corrupted(self, mock_post):
        """测试实例状态永久故障"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStateCorrupted",
                    "Message": "请求不支持永久故障的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-corrupted"]}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStateCorrupted"

    @patch('requests.post')
    def test_instance_state_enter_rescue_mode(self, mock_post):
        """测试实例进入救援模式"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStateEnterRescueMode",
                    "Message": "请求不支持进入救援模式的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-enter-rescue"]}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStateEnterRescueMode"

    @patch('requests.post')
    def test_instance_state_exit_rescue_mode(self, mock_post):
        """测试实例退出救援模式"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStateExitRescueMode",
                    "Message": "请求不支持正在退出救援模式的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-exit-rescue"]}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStateExitRescueMode"

    @patch('requests.post')
    def test_instance_state_frozen(self, mock_post):
        """测试实例已冻结"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStateFreezing",
                    "Message": "操作不支持已冻结的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-frozen"]}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStateFreezing"

    @patch('requests.post')
    def test_instance_state_isolating(self, mock_post):
        """测试实例正在隔离"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStateIsolating",
                    "Message": "请求不支持正在隔离状态的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-isolating"]}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStateIsolating"

    @patch('requests.post')
    def test_instance_state_pending(self, mock_post):
        """测试实例创建未完成"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStatePending",
                    "Message": "请求不支持创建未完成的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-pending"]}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStatePending"

    @patch('requests.post')
    def test_instance_state_rebooting(self, mock_post):
        """测试实例正在重启"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStateRebooting",
                    "Message": "请求不支持正在重启的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-rebooting"]}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStateRebooting"

    @patch('requests.post')
    def test_instance_state_rescue_mode(self, mock_post):
        """测试实例处于救援模式"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStateRescueMode",
                    "Message": "请求不支持救援模式的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-rescue"]}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStateRescueMode"

    @patch('requests.post')
    def test_instance_state_running(self, mock_post):
        """测试实例已运行"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStateRunning",
                    "Message": "请求不支持开机状态的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-running"]}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStateRunning"

    @patch('requests.post')
    def test_instance_state_service_live_migrate(self, mock_post):
        """测试实例正在服务迁移"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStateServiceLiveMigrate",
                    "Message": "不支持正在服务迁移的实例，请稍后再试"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-migrating"]}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStateServiceLiveMigrate"

    @patch('requests.post')
    def test_instance_state_shutdown(self, mock_post):
        """测试实例已隔离"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStateShutdown",
                    "Message": "请求不支持隔离状态的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-shutdown"]}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStateShutdown"

    @patch('requests.post')
    def test_instance_state_starting(self, mock_post):
        """测试实例正在开机"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStateStarting",
                    "Message": "实例开机中，不允许该操作"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-starting"]}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStateStarting"

    @patch('requests.post')
    def test_instance_state_stopped(self, mock_post):
        """测试实例已关机"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStateStopped",
                    "Message": "请求不支持已关机的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-stopped"]}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStateStopped"

    @patch('requests.post')
    def test_instance_state_stopping(self, mock_post):
        """测试实例正在关机"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStateStopping",
                    "Message": "请求不支持正在关机的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-stopping"]}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStateStopping"

    @patch('requests.post')
    def test_instance_state_terminated(self, mock_post):
        """测试实例已销毁"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStateTerminated",
                    "Message": "不支持已销毁的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-terminated"]}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStateTerminated"

    @patch('requests.post')
    def test_instance_state_terminating(self, mock_post):
        """测试实例正在销毁"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnsupportedOperation.InstanceStateTerminating",
                    "Message": "请求不支持正在销毁的实例"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-terminating"]}
        result = send_request("StartInstances", params)
        assert result["Response"]["Error"]["Code"] == "UnsupportedOperation.InstanceStateTerminating"


# 启动测试函数
def run_tests():
    pytest.main([__file__, "-v", "-s"])


if __name__ == "__main__":
    run_tests()